/*
 * SatelliteInterface.h
 *
 *  Created on: 25.05.2011
 *      Author: ansuz
 */

#ifndef SATELLITEINTERFACE_H_
#define SATELLITEINTERFACE_H_

#include "worker-monitor-topics.h"
#include <vector>
#include "resumer.h"
#include <utility>


/**
 * Class SatelliteInterface
 * Represents an interface to the satellite through which one can communicate with it and which collects some
 * information about the current setup within the satellite.
 */
class SatelliteInterface : public Thread {
private:
	///Maximum number of pings which may remain unanswered until a node is declared non-functional
	static const int maxPing;

	///Holds a list of nodes
	std::vector<std::pair<int,int> > nodelist;
	///Buffer for incoming messages from the satellite
	Fifo<WMMessage,32> SatelliteBuffer;
	///Subscriber to the message topic
	Subscriber SatelliteSubscriber;

	///Holds the worker ID
	int WorkerID;
	///Ping count
	int PingCount;
	///Holds the operation mode currently set
	operationMode oMode;

	///Sends a ping broadcast
	void Ping();

	///Ping to workers
	void WorkerPing();

	///Processes all messages in the message buffer
	void handleMessages();

	///Inherited from Thread
	void run();

	///Inherited from Thread
	void init();

public:
	///Constructor
	SatelliteInterface();


	///Returns the number of nodes (functioning and non-functioning)
	int getNumNodes();

	///Returns the number of non-functioning nodes
	int getNumUnresponsiveNodes();

	///Returns the number of functioning nodes
	int getNumResponsiveNodes();

	///Returns the list of non-functioning nodes
	int* getUnresponsiveNodes();

	///Returns the list of functioning nodes
	int* getResponsiveNodes();

	///Returns the list of nodes (functioning and non-functioning)
	int* getNodeIDList();

	/**
	 * @param ID ID of the Node to be checked
	 * @returns true if the Node exists
	 */
	bool existNode(int ID);

	///Returns the worker nodes id
	int getWorkerID();


	/**
	 * Makes a specific node the worker
	 * @param ID ID of the node to be the new worker
	 */
	void setWorker(int ID);

	/**
	 * Makes a specific node a monitor
	 * @param ID ID of the node to become a monitor
	 */
	void setMonitor(int ID);


	///Returns the operation mode
	operationMode getMode();

	/**
	 * Sets the operation mode
	 * @param mode The new mode of operation
	 */
	void setMode(operationMode mode);

	/**
	 * Sets the time between two published StatusData topics.
	 * @param time Time between two topics in milliseconds
	 */
	void setPublishPeriod(long time);

	/**
	 * Commands the worker to stop all StatusData publishing.
	 */
	void setPublishStatusData(bool send);


	///Updates all data regarding the satellite
	void updateSatellite();

};

static SatelliteInterface satelliteInterface;

static LinkinterfaceUDP linkToNodes;
static Gateway topicGateway(&linkToNodes);
static Resumer gatewayResumer;

#endif /* SATELLITEINTERFACE_H_ */
